﻿#include "PyFITKSEABeam.h"

#include "FITKAcousticsDiscModel.h"
#include "FITKAcousticsSEAModel.h"
#include "FITKSEASubSysBeam.h"
#include "FITKAcousticsDiscNodeList.h"
#include "FITKSEASubSysGeoProp.h"
#include "FITKAbstractSEASubSys.h"
//#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyBeam.h" //?
#include "FITK_Kernel/FITKCore/FITKAbstractDataManagerPrivate.h"


namespace Acoustics
{
    PyFITKSEABeam::PyFITKSEABeam(const QString & name)
    {
        //获取子系统管理器
        Acoustics::FITKAcousticsDiscModel* disc = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!disc)return;
        Acoustics::FITKAcousticsSEAModel* model = disc->getSEAModel();
        if (!model)return;
        Acoustics::FITKAcousticsSEASubSysManager* manager = model->getSEASubSysManager();
        if (!manager)return;
        //获取对象并判断类型
        Acoustics::FITKAbstractSEASubSys* absSys = manager->getDataByName(name);
        if (!absSys)return;

        if (absSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEABeam)
            _beamObject = dynamic_cast<Acoustics::FITKSEASubSysBeam*>(absSys);
    }

    int PyFITKSEABeam::getBeamID()
    {
        if (_beamObject) return _beamObject->getDataObjectID();
        return -1;
    }

    bool PyFITKSEABeam::addPoint(int pointId)
    {
        //获取节点管理器
        Acoustics::FITKAcousticsDiscModel* discModel = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!discModel)return false;
        Acoustics::FITKAcousticsDiscNodeList* discNodesList = discModel->getNodes();
        if (!discNodesList)return false;

        //判断id是否存在
        if (!discNodesList->getNodeByID(pointId))return false;

        //添加点
        Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode point{ pointId, Acoustics::FITKAbstractSEASubSysWithNodes::Path };
        _points.append(point);
        return true;
    }

    bool PyFITKSEABeam::createBeam()
    {
        if (_points.size() < 3) return false;

    //添加节点链表
        _points[0]._type = Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNodeType::Start;
        _points[_points.size() - 1]._type = Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNodeType::Finish;
        _beamObject = new Acoustics::FITKSEASubSysBeam();
        _beamObject->setNodes(_points);
        //QString name = this->ckeckNameFromMgr("Beam");
        //_beamObject->setDataObjectName(name);

    //更新几何属性
        _beamObject->updateGeoProp();

    //添加梁到子系统管理器
        Acoustics::FITKAcousticsDiscModel* disc = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!disc)return false;
        Acoustics::FITKAcousticsSEAModel* model = disc->getSEAModel();
        if (!model)return false;
        Acoustics::FITKAcousticsSEASubSysManager* manager = model->getSEASubSysManager();
        if (!manager)return false;
        manager->appendDataObj(_beamObject);

        return true;
    }

    QString PyFITKSEABeam::getName()
    {
        if (_beamObject)
            return _beamObject->getDataObjectName();
        return QString();
    }

    bool PyFITKSEABeam::setName(const QString & name)
    {
        if (name == ""||!_beamObject)return false;

        //获取子系统管理器
        Acoustics::FITKAcousticsDiscModel* disc = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!disc)return false;
        Acoustics::FITKAcousticsSEAModel* model = disc->getSEAModel();
        if (!model)return false;
        Acoustics::FITKAcousticsSEASubSysManager* manager = model->getSEASubSysManager();
        if (!manager)return false;

        //获取名称-查重处理
        if (manager->getDataByName(name) && _beamObject->getDataObjectName() != name)return false;

        _beamObject->setDataObjectName(name);
        return true;
    }

    bool PyFITKSEABeam::setPhysicalProp(const QString & Prop)
    {
        if (!_beamObject || Prop == "" || !_propMgr) return false;

        Core::FITKAbstractDataObject* data = _propMgr->getDataObjectByName(Prop);
        /**********需判断类型data************/
        if (data == nullptr) return false;
        int id = data->getDataObjectID();

        _beamObject->setPropSection(id);
        return true;
    }

    bool PyFITKSEABeam::setDamping(int type, const QString & damping)
    {
        if (!_beamObject || damping == "" || type < 1 || type>4 ||!_spectraMgr) return false;

      //获取字符串对应阻尼id
        if (_spectraMgr == nullptr) return false;
        Core::FITKAbstractDataObject* obj = _spectraMgr->getDataObjectByName(damping);
        if (obj == nullptr) return false;
        int id = obj->getDataObjectID();

        if (type == 1) {
            _beamObject->setFlexureXSpectraID(id);
        }
        else if (type == 2) {
            _beamObject->setFlexureYSpectraID(id);
        }
        else if (type == 3) {
            _beamObject->setExtensionZSpectraID(id);
        }
        else if (type == 4) {
            _beamObject->setTorsionZZSpectraID(id);
        }
        return true;
    }

    bool PyFITKSEABeam::setSEAMatrixSolution(int type, bool isSolution)
    {
        if (!_beamObject || type < 1 || type>4)return false;
        if (type == 1)
            _beamObject->setFlexureXInSEAMatrixSolution(isSolution);
        else if (type == 2)
            _beamObject->setFlexureYInSEAMatrixSolution(isSolution);
        else if (type == 3)
            _beamObject->setExtensionZInSEAMatrixSolution(isSolution);
        else if (type == 4)
            _beamObject->setTorsionZZInSEAMatrixSolution(isSolution);
        return true;
    }

    bool PyFITKSEABeam::setModalDensity(int type, bool isModalDensity, const QString&  modalDensity)
    {
        if (!_beamObject || type < 1 || type>4 || !_spectraMgr)return false;

        Core::FITKAbstractDataObject* data = _spectraMgr->getDataObjectByName(modalDensity);
        /**********需判断类型data************/
        if (data == nullptr && modalDensity != "") return false;
        int id = -1;
        if (data) id = data->getDataObjectID();

        if (type == 1) {
            _beamObject->setFlexureXModelDensityState(isModalDensity);
            if (id != -1)_beamObject->setFlexureXModelDensityID(id);
        }
        else if (type == 2) {
            _beamObject->setFlexureYModelDensityState(isModalDensity);
            if (id != -1)_beamObject->setFlexureYModelDensityID(id);
        }
        else if (type == 3) {
            _beamObject->setExtensionZModelDensityState(isModalDensity);
            if (id != -1)_beamObject->setExtensionZModelDensityID(id);
        }
        else if (type == 4) {
            _beamObject->setTorsionZZModelDensityState(isModalDensity);
            if (id != -1)_beamObject->setTorsionZZModelDensityID(id);
        }
        return true;
    }

    QString PyFITKSEABeam::getGeometryProp()
    {
        if (!_beamObject) return "Get Physics Property Error";
        //梁的横截面周长和横截面面积暂时忽略
        //Acoustics::FITKPhyscisPropertyBeam* beamPhyPropData = dynamic_cast<Acoustics::FITKPhyscisPropertyBeam*>(_beamObject->getPropSectionObj());
        //if (!beamPhyPropData) return "Get Physics Property Error";

        double length = _beamObject->getGeoProp()->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Circumference);
        //double perimeter = beamPhyPropData->getPerimeter();
        // double area = beamPhyPropData->getCrossSectionArea();
        // QString pro = QString("Length is %1, Cross-section perimeter is %2, Cross-section area is %3").arg(length).arg(perimeter).arg(area);
        QString pro = QString("Length is %1").arg(length);
        return pro;
    }

    QString PyFITKSEABeam::ckeckNameFromMgr(QString name)
    {
        Acoustics::FITKAcousticsDiscModel* discModel = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!discModel)return name;
        Acoustics::FITKAcousticsSEAModel* seaModel = discModel->getSEAModel();
        if (!seaModel)return name;
        Acoustics::FITKAcousticsSEASubSysManager* subSysMgr = seaModel->getSEASubSysManager();
        if (!subSysMgr) return name;

        return subSysMgr->checkName(name);
    }
}